package cn.iocoder.yudao.module.mqtt.framework.handler;

import cn.iocoder.yudao.module.mqtt.framework.util.MqttContextHolder;
import cn.iocoder.yudao.module.mqtt.service.mqtt.MqttMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Component;

/**
 * 多MQTT实例消息处理器
 * 支持多个MQTT实例的消息处理
 *
 * @author 芋道源码
 */
@Slf4j
@Component
public class MultiMqttMessageHandler implements MessageHandler {

    @Autowired
    private MqttMessageService mqttMessageService;

    @Override
    public void handleMessage(Message<?> message) throws MessagingException {
        try {
            String payload = message.getPayload().toString();
            MessageHeaders headers = message.getHeaders();
            
            // 调试：打印所有消息头
            log.info("MQTT消息头信息: {}", headers);
            log.info("MQTT消息头键列表: {}", headers.keySet());
            
            // 获取主题信息
            String topicName = headers.get("mqtt_receivedTopic") != null ? 
                    headers.get("mqtt_receivedTopic").toString() : "unknown";
            
            // 获取配置ID（优先使用线程本地变量）
            Long mqttConfigId = MqttContextHolder.getConfigId();
            if (mqttConfigId == null) {
                // 从消息头中获取配置ID
                if (headers.get("mqtt_configId") != null) {
                    mqttConfigId = Long.valueOf(headers.get("mqtt_configId").toString());
                } else if (headers.get("mqtt_receivedConfigId") != null) {
                    mqttConfigId = Long.valueOf(headers.get("mqtt_receivedConfigId").toString());
                }
            }
            
            // 获取客户端ID（优先使用线程本地变量）
            String clientId = MqttContextHolder.getClientId();
            if (clientId == null) {
                // 从消息头中获取
                if (headers.get("mqtt_receivedClientId") != null) {
                    clientId = headers.get("mqtt_receivedClientId").toString();
                } else if (headers.get("mqtt_clientId") != null) {
                    clientId = headers.get("mqtt_clientId").toString();
                } else {
                    // 尝试从其他可能的键获取
                    for (String key : headers.keySet()) {
                        if (key.toLowerCase().contains("client") || key.toLowerCase().contains("clientid")) {
                            clientId = headers.get(key).toString();
                            log.debug("从键 {} 获取到客户端ID: {}", key, clientId);
                            break;
                        }
                    }
                }
            }
            
            // 如果仍然没有配置ID，尝试从客户端ID解析
            if (mqttConfigId == null) {
                mqttConfigId = extractMqttConfigId(clientId);
            }
            
            // 清理线程本地变量
            MqttContextHolder.clear();
            
            // 获取消息ID
            String messageId = headers.get("mqtt_id") != null ? 
                    headers.get("mqtt_id").toString() : null;
            
            // 获取QoS
            Integer qos = headers.get("mqtt_qos") != null ? 
                    Integer.valueOf(headers.get("mqtt_qos").toString()) : 0;
            
            // 获取retained标志
            Boolean retained = headers.get("mqtt_retained") != null ? 
                    Boolean.valueOf(headers.get("mqtt_retained").toString()) : false;
            
            // 配置ID已经在上面获取了
            
            log.info("收到MQTT消息 - 配置ID: {}, 主题: {}, 客户端ID: {}, 内容: {}", 
                    mqttConfigId, topicName, clientId, payload);
            
            // 保存消息到数据库
            mqttMessageService.saveReceivedMessage(mqttConfigId, topicName, payload, qos, retained, clientId, messageId);
            
            // 根据主题进行业务处理
            processMessageByTopic(mqttConfigId, topicName, payload);
            
        } catch (Exception e) {
            log.error("处理MQTT消息时发生错误", e);
        }
    }

    /**
     * 从客户端ID中提取MQTT配置ID
     * 这里可以根据实际需求调整解析逻辑
     */
    private Long extractMqttConfigId(String clientId) {
        if (clientId == null) {
            return 1L; // 默认配置ID
        }
        
        // 根据客户端ID模式提取配置ID
        // 例如：sub_client_id_123 -> 配置ID为1
        if (clientId.contains("sub_client_id_123")) {
            return 1L;
        }
        
        // 示例：如果客户端ID格式为 "sub_client_id_123_config_1"，则提取配置ID为1
        if (clientId.contains("config_")) {
            try {
                String configIdStr = clientId.substring(clientId.lastIndexOf("config_") + 7);
                return Long.valueOf(configIdStr);
            } catch (Exception e) {
                log.warn("无法从客户端ID中解析配置ID: {}", clientId);
            }
        }
        
        // 如果无法解析，使用默认配置ID
        return 1L;
    }

    /**
     * 根据主题进行业务处理
     */
    private void processMessageByTopic(Long mqttConfigId, String topicName, String payload) {
        // 这里可以根据不同的主题进行不同的业务处理
        switch (topicName) {
            case "atguigu/iot/lamp/line":
                processLampLineMessage(mqttConfigId, payload);
                break;
            case "atguigu/iot/lamp/device/status":
                processLampStatusMessage(mqttConfigId, payload);
                break;
            default:
                log.info("未识别的主题: {}, 内容: {}", topicName, payload);
                break;
        }
    }

    /**
     * 处理路灯在线状态消息
     */
    private void processLampLineMessage(Long mqttConfigId, String payload) {
        log.info("处理路灯在线状态消息 - 配置ID: {}, 内容: {}", mqttConfigId, payload);
        // TODO: 实现具体的业务逻辑
        // tbLampService.updateLampOnlineStatus(payload);
    }

    /**
     * 处理路灯设备状态消息
     */
    private void processLampStatusMessage(Long mqttConfigId, String payload) {
        log.info("处理路灯设备状态消息 - 配置ID: {}, 内容: {}", mqttConfigId, payload);
        // TODO: 实现具体的业务逻辑
        // tbLampStatusService.saveDeviceStatus(payload);
    }
} 